from typing import List, NamedTuple
import argparse
from enum import Enum
from collections import namedtuple

from message import MessageTerminal


message_terminal_object = MessageTerminal()

class DataFrom(Enum):
    """ Возможные виды источников входных данных """

    TERMINAL = 'terminal'


class InputDataFromUser:
    """ Получаем входные данные от пользователя """

    def __init__(self, data_from: DataFrom):
        self.data_from = data_from

    def get_data_from_specified_source(self) -> NamedTuple:
        """ Получаем входные данные из указанного источника """

        match self.data_from.value:
            case 'terminal':
                input_data = InputDataFromUserFromTerminal().get_input_data()
                return input_data
            case _:
                message = 'The passed argument is not processed: ' + \
                          self.data_from.value
                raise ValueError(message)

    def get_input_data(self) -> NamedTuple:
        raise NotImplementedError


class InputDataFromUserFromTerminal(InputDataFromUser):
    """ Получаем входные данные от пользователя из терминала """

    def __init__(self):
        pass

    def get_base_object_for_arguments(self) -> argparse.ArgumentParser:
        """ Получаем базовый объект для аргументов """

        parser = argparse.ArgumentParser()
        parser.add_argument(
            '-l',
            '--link_to_video',
            type=str,
            help='Link to the video for download'
        )

        parser.add_argument(
            '--all-download',
            choices=['yes'],
            dest='is_all_downloads',
            help='Show all video download options',
        )
        return parser

    def get_list_of_created_arguments(self) -> List[NamedTuple]:
        """ Получаем список из созданных аргументов """

        list_of_created_arguments = []
        Parameter = namedtuple('Parameter', ['keys', 'value'])
        parser = self.get_base_object_for_arguments()

        for element in parser._actions:
            keys = ' or '.join(element.option_strings)
            value = element.help
            parameter = Parameter(keys, value)
            list_of_created_arguments.append(parameter)

        return list_of_created_arguments

    def get_input_data(self) -> NamedTuple:
        """ Получаем входные данные из переданных аргументов """

        parser = self.get_base_object_for_arguments()
        arguments = parser.parse_args()

        is_passed_arguments = any(
            [argument[1] for argument in arguments._get_kwargs()]
        )
        if not is_passed_arguments:
            message_terminal_object.show_list_of_available_arguments()
            exit(1)

        return arguments


    def get_user_selected_response(self):
        """ Получаем выбранный ответ пользователя """

        response = input('>>> ')
        return response
